const mongoose = require('mongoose');
const BaseDao = {

	/**
	 * 针对单个collect的upsert方法
	 * @param  {[Object]}   updateDoc [用于保存或是更新的document，如果doc中有_id则视为是更新，否则视为新增]
	 * @param  {Function} callback  [description]
	 * @return {[type]}             [description]
	 */
	save : function(updateDoc,callback){
		if(!updateDoc._id){
			updateDoc._id = mongoose.Types.ObjectId();
		}
		this.model.findOneAndUpdate({_id : updateDoc._id},updateDoc,{upsert : true , new : true},callback);
	},
	
	/**
	 * 基于aggregate的查询。以当前Model对应的collect为初始Input。
	 * @param  {[Array]}   aggregateStages [对应于aggregate的pipeline中的各个环节]
	 * aggregateStages[0]必须是$match
	 * @param  {[Object]}   options       [如果需要对结果集进行分页、排序显示，则需要这个参数。]
	 * 可以选择的的有skip、limit、sort格式参见MongoDB文档
	 * 如果没有传递options参数，则返回所有符合条件的结果集
	 */
	query : function(aggregateStages, options, callback){

		if(typeof options === 'function'){
			callback = options;
			options = options || {};
		}

		aggregateStages = aggregateStages || [{ "$match": {} }];

		let listOperations = [];
		if(options.skip){
			listOperations.push({ "$skip" : options.skip });
		}
		if(options.limit){
			listOperations.push({ "$limit" : options.limit });
		}
		if(options.sort){
			listOperations.push({ "$sort" : options.sort });
		}

		this.model.aggregate(aggregateStages.concat(listOperations), (err , docs) => {
			callback(err, docs);
		});

	},

	count : function(queryStage, callback){

		let aggregateStages = [...queryStage, {'$count': 'total'}];
		this.query(aggregateStages, (err, ret) => {
			if(!err){
				callback(err, ret[0] ? ret[0].total : 0);
				return;
			}
			callback(err);
		});
	},

	remove: function(cond,callback){
		this.model.deleteOne(cond,callback)
	}

};

module.exports = BaseDao;